home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / MacPowerオリジナル / キョービのプログラマー / Flash Trash src / Flash Trash.c next >
C/C++ Source or Header  |  1997-10-06  |  7KB  |  240 lines

  1. #include <A4Stuff.h>
  2. #include <SetupA4.h>
  3. #include <Files.h>
  4. #include <Traps.h>
  5. #include <Sound.h>
  6.  
  7. /*------------- main routine -------------*/
  8. void main(void);
  9.  
  10. /*------------- initialize routines -------------*/
  11. Boolean load_resources(void);
  12. Handle load_one_resource(ResType res_type, short res_id);
  13. void install_trap(void);
  14.  
  15. /*------------- my GetResource routine -------------*/
  16. typedef pascal Handle (*GetResourceProc)(ResType res_type, short res_id);
  17. typedef pascal Handle (*Get1ResourceProc)(ResType res_type, short res_id);
  18. pascal Handle my_GetResource(ResType res_type, short res_id);
  19. pascal Handle my_Get1Resource(ResType res_type, short res_id);
  20. void check_and_replace_icon(ResType res_type, short res_id, Handle h);
  21. void copy_handle(Handle src, Handle dst);
  22.  
  23. /*------------- flush sound routine -------------*/
  24. void setup_flush_sound(void);
  25. void snd_stop(void);
  26. void start_flush_sound(void);
  27.  
  28. /*------------- my PBHDelete routine -------------*/
  29. OSErr my_pbhdelete(void);
  30. OSErr asm call_original_pbhdelete(long pb, long call_addr);
  31. long asm get_a0(void);
  32. void asm set_a0(long pb);
  33.  
  34. /*------------- inline asm -------------*/
  35. void push_d0_and_a0(void)    TWOWORDINLINE(0x48E7, 0x8080);    // MOVEM.L   D0/A0,-(A7)
  36. void pop_d0_and_a0(void)    TWOWORDINLINE(0x4CDF, 0x0101);    // MOVEM.L   (A7)+,D0/A0
  37.  
  38. /*------------- global -------------*/
  39. long                original_pbhdelete;
  40. GetResourceProc        old_GetResource;
  41. Get1ResourceProc    old_Get1Resource;
  42. Handle                empty_icl4, empty_icl8, empty_ICN, empty_ics, empty_ics4, empty_ics8;
  43. Handle                fat_icl4, fat_icl8, fat_ICN, fat_ics, fat_ics4, fat_ics8;
  44. Handle                flush_sound;
  45. SndChannelPtr        snd_chan_ptr;
  46. Boolean                snd_chan_ready;
  47.  
  48. void main(void)
  49. {
  50. long    old_A4;
  51.     old_A4 = SetCurrentA4();
  52.     RememberA4();
  53.     if(load_resources()) {
  54.         install_trap();
  55.         setup_flush_sound();
  56.         ShowInitIcon(128, -1);
  57.     } else {
  58.         ShowInitIcon(129, -1);
  59.     }
  60.     SetA4(old_A4);
  61. }
  62.  
  63. /*------------- initialize routines -------------*/
  64. Boolean load_resources(void)
  65. {
  66.     if(load_one_resource('INIT', 0) == nil) return false;
  67.     if((empty_icl4 = load_one_resource('icl4', 130)) == nil) return false;
  68.     if((empty_icl8 = load_one_resource('icl8', 130)) == nil) return false;
  69.     if((empty_ICN = load_one_resource('ICN#', 130)) == nil) return false;
  70.     if((empty_ics = load_one_resource('ics#', 130)) == nil) return false;
  71.     if((empty_ics4 = load_one_resource('ics4', 130)) == nil) return false;
  72.     if((empty_ics8 = load_one_resource('ics8', 130)) == nil) return false;
  73.     if((fat_icl4 = load_one_resource('icl4', 131)) == nil) return false;
  74.     if((fat_icl8 = load_one_resource('icl8', 131)) == nil) return false;
  75.     if((fat_ICN = load_one_resource('ICN#', 131)) == nil) return false;
  76.     if((fat_ics = load_one_resource('ics#', 131)) == nil) return false;
  77.     if((fat_ics4 = load_one_resource('ics4', 131)) == nil) return false;
  78.     if((fat_ics8 = load_one_resource('ics8', 131)) == nil) return false;
  79.     return true;
  80. }
  81.  
  82. Handle load_one_resource(ResType res_type, short res_id)
  83. {
  84. Handle    h;
  85.     h = Get1Resource(res_type, res_id);
  86.     if(h) {
  87.         HNoPurge(h);
  88.         DetachResource(h);
  89.         MoveHHi(h);
  90.         HLock(h);
  91.     }
  92.     return h;
  93. }
  94.  
  95. void install_trap(void)
  96. {
  97.     original_pbhdelete = (long)GetOSTrapAddress(_HDelete);
  98.     SetOSTrapAddress((UniversalProcPtr)my_pbhdelete, _HDelete);
  99.     
  100.     old_GetResource = (GetResourceProc)GetToolTrapAddress(_GetResource);
  101.     SetToolTrapAddress((UniversalProcPtr)my_GetResource, _GetResource);
  102.     
  103.     old_Get1Resource = (Get1ResourceProc)GetToolTrapAddress(_Get1Resource);
  104.     SetToolTrapAddress((UniversalProcPtr)my_Get1Resource, _Get1Resource);
  105. }
  106.  
  107. /*------------- my GetResource routine -------------*/
  108. pascal Handle my_GetResource(ResType res_type, short res_id)
  109. {
  110. Handle    h = nil;
  111. long    oldA4;
  112.     oldA4 = SetUpA4();
  113.     h = old_GetResource(res_type, res_id);
  114.     check_and_replace_icon(res_type, res_id, h);
  115.     RestoreA4(oldA4);
  116.     return h;
  117. }
  118.  
  119. pascal Handle my_Get1Resource(ResType res_type, short res_id)
  120. {
  121. Handle    h = nil;
  122. long    oldA4;
  123.     oldA4 = SetUpA4();
  124.     h = old_Get1Resource(res_type, res_id);
  125.     check_and_replace_icon(res_type, res_id, h);
  126.     RestoreA4(oldA4);
  127.     return h;
  128. }
  129.  
  130. void check_and_replace_icon(ResType res_type, short res_id, Handle h)
  131. {
  132.     if(res_id == -3993) {
  133.         if(res_type == 'icl4') copy_handle(empty_icl4, h);
  134.         if(res_type == 'icl8') copy_handle(empty_icl8, h);
  135.         if(res_type == 'ICN#') copy_handle(empty_ICN, h);
  136.         if(res_type == 'ics#') copy_handle(empty_ics, h);
  137.         if(res_type == 'ics4') copy_handle(empty_ics4, h);
  138.         if(res_type == 'ics8') copy_handle(empty_ics8, h);
  139.     }
  140.     if(res_id == -3984) {
  141.         if(res_type == 'icl4') copy_handle(fat_icl4, h);
  142.         if(res_type == 'icl8') copy_handle(fat_icl8, h);
  143.         if(res_type == 'ICN#') copy_handle(fat_ICN, h);
  144.         if(res_type == 'ics#') copy_handle(fat_ics, h);
  145.         if(res_type == 'ics4') copy_handle(fat_ics4, h);
  146.         if(res_type == 'ics8') copy_handle(fat_ics8, h);
  147.     }
  148. }
  149.  
  150. void copy_handle(Handle src, Handle dst)
  151. {
  152. long    src_size, dst_size;
  153.     if(src && dst) {
  154.         src_size = GetHandleSize(src);
  155.         dst_size = GetHandleSize(dst);
  156.         if(src_size == dst_size)
  157.             BlockMove(*src, *dst, src_size);
  158.     }
  159. }
  160.  
  161. /*------------- flush sound routine -------------*/
  162. void setup_flush_sound(void)
  163. {
  164.     flush_sound = load_one_resource('snd ', 128);
  165.     snd_chan_ptr = nil;
  166.     snd_chan_ready = false;
  167.     snd_chan_ptr = (SndChannelPtr)NewPtrSysClear(sizeof(SndChannel));
  168.     if(snd_chan_ptr)
  169.         snd_chan_ptr->qLength = stdQLength;
  170. }
  171.  
  172. void snd_stop(void)
  173. {
  174.     if(snd_chan_ready) {
  175.         SndDisposeChannel(snd_chan_ptr, true);
  176.         snd_chan_ptr->qLength = stdQLength;
  177.         snd_chan_ready = false;
  178.     }
  179. }
  180.  
  181. void start_flush_sound(void)
  182. {
  183.     if(snd_chan_ready)
  184.         snd_stop();
  185.     if(flush_sound)
  186.         if(SndNewChannel(&snd_chan_ptr, sampledSynth, 0, nil) == 0) {
  187.             snd_chan_ready = true;
  188.             SndPlay(snd_chan_ptr, (SndListHandle)flush_sound, true);
  189.         }
  190. }
  191.  
  192. /*------------- my PBHDelete routine -------------*/
  193. OSErr my_pbhdelete(void)
  194. {
  195. HFileParamPtr    pb;
  196. short            err;
  197. long            old_A4;
  198. short            trash_vrefnum;
  199. long            trash_dirid;
  200.     push_d0_and_a0();    // save d0 and a0 into stack
  201.     old_A4 = SetUpA4();    // setup global base
  202.     pop_d0_and_a0();    // load d0 and a0 into stack
  203.     pb = (HFileParamPtr)get_a0();        // get a0(ParamBlockPtr)
  204.     err = call_original_pbhdelete((long)pb, original_pbhdelete); // call original trap
  205.     pb = (HFileParamPtr)get_a0();
  206.     if(err == 0)
  207.         if(FindFolder(pb->ioVRefNum, kTrashFolderType, false, &trash_vrefnum, &trash_dirid) == 0)
  208.             if(trash_dirid == pb->ioDirID)
  209.                 start_flush_sound();
  210.     set_a0((long)pb); // re load A0 for safe
  211.     RestoreA4(old_A4);
  212.     return err;
  213. }
  214.  
  215. OSErr asm call_original_pbhdelete(long pb, long call_addr)
  216. {
  217.     fralloc +
  218.     movem.l        D1-D7/A1-A6, -(A7)
  219.     move.l        pb, a0
  220.     move.l        call_addr, a1
  221.     jsr            (a1)
  222.     movem.l        (A7)+,D1-D7/A1-A6
  223.     frfree
  224.     rts
  225. }
  226.  
  227. long asm get_a0(void)
  228. {
  229.     move.l        a0, d0
  230.     rts
  231. }
  232.  
  233. void asm set_a0(long pb)
  234. {
  235.     fralloc +
  236.     move.l        pb, a0
  237.     frfree
  238.     rts
  239. }
  240.